package com.luo.demo.security.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;

/**
 * OIDC end_session_endpoint 登出处理器
 *
 * @author luohq
 * @date 2022-02-22 21:04
 */
@Slf4j
@Deprecated
public class OidcEndSessionLogoutSuccessHandler implements LogoutSuccessHandler {
    private String uriFormat = "%s?id_token_hint=%s";
    private String uriFormatWithPostLogoutRedirectUri = "%s?id_token_hint=%s&post_logout_redirect_uri=%s";

    private String endSessionEndpointUri;
    private String postLogoutRedirectUri;

    public OidcEndSessionLogoutSuccessHandler(String endSessionEndpointUri, String postLogoutRedirectUri) {
        this.endSessionEndpointUri = endSessionEndpointUri;
        this.postLogoutRedirectUri = postLogoutRedirectUri;
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        String idTokenVal = Optional.ofNullable(authentication)
                .map(OAuth2AuthenticationToken.class::cast)
                .map(OAuth2AuthenticationToken::getPrincipal)
                .map(DefaultOidcUser.class::cast)
                .map(DefaultOidcUser::getIdToken)
                .map(OidcIdToken::getTokenValue)
                .orElse(null);
        //OAuth2AuthenticationToken oAuth2AuthenticationToken = (OAuth2AuthenticationToken) authentication;
        //DefaultOidcUser oidcUser = (DefaultOidcUser) oAuth2AuthenticationToken.getPrincipal();
        //String idTokenVal = oidcUser.getIdToken().getTokenValue();
        if (!StringUtils.hasText(idTokenVal)) {
            log.error("IdToken should not empty when redirect to OP end_session_endpoint!");
            response400(response);
        }

        String endSessionEndpointRedirectUri = null;
        if (StringUtils.hasText(this.postLogoutRedirectUri)) {
            endSessionEndpointRedirectUri = String.format(this.uriFormatWithPostLogoutRedirectUri, this.endSessionEndpointUri, idTokenVal, this.postLogoutRedirectUri);
        } else {
            endSessionEndpointRedirectUri = String.format(this.uriFormat, this.endSessionEndpointUri, idTokenVal);
        }
        log.info("redirect OP end_session_endpoint: {}", endSessionEndpointRedirectUri);
        response.sendRedirect(endSessionEndpointRedirectUri);
    }

    private void response400(HttpServletResponse response) throws IOException {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        response.getWriter().flush();
    }
}
